#pragma once

#include <pthread.h>
#include <string>
#include <functional>


namespace ThreadMoudle
{
    class ThreadData
    {
    public:
        ThreadData(const std::string &name, pthread_mutex_t *lock)
            : _name(name), _lock(lock)
        {}
        const std::string& GetName() { return _name; }
        pthread_mutex_t* GetLock() { return _lock; }
    private:
        std::string _name;
        pthread_mutex_t *_lock;
    };



    // 线程要执行的方法
    // using func_t = std::function<void()>;
    typedef void (*func_t)(ThreadData* td);

    class Thread
    {
    public:
        void Excute()
        {
            _isrunning = true;
            _func(_td);
            _isrunning = false;
        }
    public:
        Thread(const std::string name, func_t func, ThreadData* td)
            : _name(name), _func(func), _isrunning(false), _td(td)
        {
            std::cout << "Create " << _name << " done..." << std::endl;
        }

        // 此方法若不为静态，则参数无法和 pthread_create 所需进行匹配（隐含参数 this 指针）
        static void *ThreadRoutine(void *args)
        {
            Thread* self = static_cast<Thread*>(args);  // 获得当前对象 
            self->Excute();
            return nullptr;
        }

        bool Start()
        {
            int n = ::pthread_create(&_tid, nullptr, ThreadRoutine, this);
            if (n != 0)
                return false;
            else
                return true;
        }

        std::string Status()
        {
            if (_isrunning) return "Running...";
            else return "sleeping...";
        }

        void Stop()
        {
            if (_isrunning)
            {
                pthread_cancel(_tid);
                _isrunning = false;
            }
        }

        void Join()
        {
            ::pthread_join(_tid, nullptr);
            delete _td;
        }

        std::string GetName()
        {
            return _name;
        }

        ~Thread()
        {
        }

    private:
        std::string _name;     // 线程名
        pthread_t _tid;        // 线程 ID
        bool _isrunning;       // 是否在运行
        func_t _func;          // 线程要执行的回调函数
        ThreadData* _td;        // 参数传递 
        
        
        // std::string _result;   // 线程返回结果 
    };
}